iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0

在 Next.js 中使用 Sanity Webhook 很簡單,官方也有準備好各種的套件給使用者使用,如果是有跟著本系列開啟 Next.js 專案的話,可以使用 next-sanity 底下的 webhook。

// ./app/api/revalidate/route.ts

import { revalidateTag } from "next/cache";
import { type NextRequest, NextResponse } from "next/server";
import { parseBody } from "next-sanity/webhook";

export async function POST(req: NextRequest) {
  const { body, isValidSignature } = await parseBody<{
    _type: string;
    slug?: string | undefined;
  }>(req, process.env.NEXT_PUBLIC_SANITY_HOOK_SECRET);

  if (!isValidSignature) {
    return new Response("Invalid Signature", { status: 401 });
  }

  if (!body?._type) {
    return new Response("Bad Request", { status: 400 });
  }

  revalidateTag(body?._type);
  return NextResponse.json({
    status: 200,
    revalidated: true,
    now: Date.now(),
    body,
  });
}

先找官方的範例,主要是使用 next-sanity/webhook 中的 parseBody() 方法來對 Sanity 傳過來的請求進行驗證,並且過濾出傳送過來的 body 內容。

可以看到 parseBody() 回傳了 { body, isValidSignature }
顧名思義 isValidSignature 就是是否通過驗證的標籤,如果是 false 就是沒有驗證通過。

body 則是被更動的內容資料物件,以我隨便更動一篇文章為例:

{
  _rev: 'Tpe1Rj6o9fDmGqbWvmFLMY',
  slug: { current: 'tomcat-下載、簡介' },
  _createdAt: '2024-09-30T03:04:01Z',
  tags: [ 'Tomcat', 'Java' ],
  title: 'Tomcat 下載、簡介',
  _updatedAt: '2024-10-10T10:42:18Z',
  _id: 'zyNWCmL2nqND6MCG2waPb',
  _type: 'blogPost',
  subtitle: 'Tomcat 下載、簡介',
  content: '講 Tomcat 之前要先稍微講一下什麼是 __容器 ( Container )__,\n' +
    '其實容器也就是一個 Java 寫的程式,運行於我們的 JVM 上面,不同的容器負責不同的工作。\n' +
    '__Web 容器 (Web Container)__\n' +
    // ...
    'ok! 這樣我們的 Tomcat 開發環境就算是裝好了~',
  publishedAt: '2020-05-04',
  heroImage: { _type: 'image', asset: [Object] }
}

可以看到 body 是全部的內容,並不是只有被更動到的欄位內容。
若是想要有些更複雜的回傳可以針對建立的 Projection 進行編輯:

https://ithelp.ithome.com.tw/upload/images/20241010/20101989kzL2EHERuT.jpg

這邊舉幾個例子,如果我設定成這樣:

{ _type, title }

https://ithelp.ithome.com.tw/upload/images/20241010/20101989tpltqdTNPi.jpg

回傳就是這樣:

{
	_type: 'blogPost',
	title: 'Tomcat 下載、簡介'
}

基本上回傳就是自己指定的內容。

再來還有一些特別的 function,Sanity 將其歸類在 Delta functions,包含了 before(), after() 等等的函式,在這邊直接展示幾項吧!

before(), after()

回傳更新前、更新後的值

假設這樣設定:

{ _type, title, "oldTag": before().tags, "newTag": after().tags }

然後我對 tags 這個欄位進行更新,就會回傳這樣的:

{
  _type: 'blogPost',
  title: 'Tomcat 下載、簡介',
  oldTag: [ 'Tomcat' ],
  newTag: [ 'Tomcat', 'Java' ]
}

delta::changedAny()

監聽指定欄位是否有更定,回傳值是 boolean

{ _type, title, "hasTagsChanged": delta::changedAny(tags) }

這樣就是指定了監聽 tags 欄位是否有更動,如果我有更動到 tags 欄位就會回傳 true,沒有的話就是 false

{ _type: 'blogPost', title: 'Tomcat 下載、簡介', hasTagsChanged: true } // <- 有更動
{ _type: 'blogPost', title: 'Tomcat 下載、簡介', hasTagsChanged: false } // <- 沒更動

同時還可以一次指定多格欄位,格式是這樣的:
( 注意還有一層小括號括起來哦! )

delta::changedAny((publishedAt, tags))

上一篇
Day 25 - Sanity Webhook 創立與 Header 解析
下一篇
Day 27 - Sanity Visual Editing
系列文
用 Sanity 跟 Nextjs 重寫個人部落格30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言